package com.speedydial;


import java.util.Calendar;
import java.util.Date;

import android.app.Activity;
import android.app.PendingIntent;
import android.content.Intent;
import android.database.Cursor;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.telephony.SmsManager;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

import com.speedydial.model.SettingsModel;

public class ListContactPendingActivity extends Activity implements SensorEventListener {
	
	private static final int ACTIVITY_EDIT=1;
    
	/** Sensor management */
	private SensorManager sensorManager;

	/** text fields */
	private TextView textLabel;
	private TextView xAccelLabel;
	private TextView yAccelLabel;
	private TextView zAccelLabel;
	private TextView confLabel;
	
	private TextView xMaxLabel, yMaxLabel, zMaxLabel;
	
	/** flag that signals the sending of sms */
	private boolean isAlreadySent;
	
	private static final String patriciaMovil = "618832981";
	private static final String lateMsg = "Estare llegando 10 minutos tarde";
	private static final String superLateMsg = "Estare llegando 20 minutos tarde";
	
	// initial values to refresh according to each orientation
	private float mInitialX = 0f;
	private float mInitialY = 0f;
	private float mInitialZ = 0f;
	
	// offset values from the database
	private float offsetX, offsetY, offsetZ;
	
	/** Weight factor for the low pass filter */
	private float mWeightFactor = 8f;
	private float mAccelLimit = 1.0f;
	
	private SettingsDBAdapter mDbHelper;
	
	private boolean initiated;
	
	private Date localTimeStamp;
	
	private long currCursor;
	
	/** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        
     // activamos el sensor
        sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
        
        setContentView(R.layout.form_layout);
        
        // init db resources
        mDbHelper = new SettingsDBAdapter(this);
        mDbHelper.open();
        
        // setting the form elements
        textLabel = (TextView) findViewById(R.id.display_text);
        textLabel.setText("X:");
        
        xAccelLabel = (TextView) findViewById(R.id.x_accel_text);
        xAccelLabel.setText("x acel");
        
        yAccelLabel = (TextView) findViewById(R.id.y_accel_text);
        zAccelLabel = (TextView) findViewById(R.id.z_accel_text);
  
        
        xMaxLabel = (TextView) findViewById(R.id.x_max);
        yMaxLabel = (TextView) findViewById(R.id.y_max);
        zMaxLabel = (TextView) findViewById(R.id.z_max);
        
        confLabel = (TextView) findViewById(R.id.confirmation);
        
        Button offsetButton = (Button) findViewById(R.id.offset_button);
        
        offsetButton.setOnClickListener(new View.OnClickListener() {

			@Override
			public void onClick(View v) {
				
				setOffsetValues();
				
				confLabel.setText("offset: " + offsetY);
				
			}
        	
        });
        
        Button button = (Button) findViewById(R.id.calibrate_button);
        
        button.setOnClickListener(new View.OnClickListener() {
			
			@Override
			public void onClick(View v) {
				Calendar cl = Calendar.getInstance();
				cl.add(Calendar.SECOND, 1);
				localTimeStamp = cl.getTime();
				confLabel.setText("reseting...");
				setAlreadySent(false);
				
				// persist new values
				SettingsModel settingX = new SettingsModel(
						SettingsDBAdapter.OrientationSettingsKey.ORIENTATION_X.toString(), 
						Float.toString(mInitialX) 
						);
				
				SettingsModel settingY = new SettingsModel(
						SettingsDBAdapter.OrientationSettingsKey.ORIENTATION_Y.toString(), 
						Float.toString(mInitialY) 
						);
				
				setCursor();
				settingY.ID = currCursor;
				
				SettingsModel settingZ = new SettingsModel(
						SettingsDBAdapter.OrientationSettingsKey.ORIENTATION_Z.toString(), 
						Float.toString(mInitialZ) 
						);
				mDbHelper.createSetting(settingX);
				mDbHelper.createSetting(settingY);
				mDbHelper.createSetting(settingZ);
				
				initiated = true;
				
				// set title as registered
				confLabel.setText("Calibrated!");
				
				xMaxLabel.setText( Float.toString(mInitialX) );
				yMaxLabel.setText( Float.toString(mInitialY) );
				zMaxLabel.setText( Float.toString(mInitialZ) );
				
				setOffsetValues();
				
				yMaxLabel.setTag( offsetY );
				
			}
		});
        
        // at the end, set the value
        setAlreadySent(false);
        
        	
    }
    
    
    private void setOffsetValues(){
    	
    	setCursor();
    	
    	// set the orientation values and get offsetX, offsetY, offsetZ
        String tmpVal = getOffset(SettingsDBAdapter.OrientationSettingsKey.ORIENTATION_X.toString());
        
        if( tmpVal != null ){
        	offsetX = Float.parseFloat(tmpVal);
        }
        
        tmpVal = getOffset(SettingsDBAdapter.OrientationSettingsKey.ORIENTATION_Y.toString());
        
        if( tmpVal != null ){
        	offsetY = Float.parseFloat(tmpVal);
        }
        
        tmpVal = getOffset(SettingsDBAdapter.OrientationSettingsKey.ORIENTATION_Z.toString());
        
        if( tmpVal != null ){
        	offsetZ = Float.parseFloat(tmpVal);
        }
	
    }
    
    private void setCursor(){
    	
    	Cursor c = mDbHelper
		.getValueByKeyName( SettingsDBAdapter.OrientationSettingsKey.ORIENTATION_Y.toString() );
    	
    	int iVal = c.getColumnIndex(SettingsDBAdapter.KEY_ROWID);
    	
    	if( iVal < 0 )
    		return;
    	
    	startManagingCursor(c);
    	
    	if( c.getCount() == 0 )
    		return;
    	
    	this.currCursor = c.getLong(iVal);
    	
    }
    
    private String getOffset(String offsetType){
    	
		Cursor c = mDbHelper
				.getValueByKeyName( offsetType );
		
		int iVal = c.getColumnIndex(SettingsDBAdapter.KEY_VALUE);
		
		if( iVal < 0 ){
			return "0";
		}
		startManagingCursor(c);
		
		if( c.getCount() == 0 )
			return "0";
		
		String res = c.getString(iVal);
		return res;
    }
    
    @Override
    protected void onResume() {
    	super.onResume();

    	// ...and the orientation sensor
    	sensorManager.registerListener(this, 
    			sensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION), 
    			SensorManager.SENSOR_DELAY_NORMAL);
    }
  
    @Override
    protected void onStop() {
    	// Unregister the listener
    	sensorManager.unregisterListener(this);
    	super.onStop();
    } 


	@Override
	public void onAccuracyChanged(Sensor arg0, int arg1) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void onSensorChanged(SensorEvent event) {

		if (event.sensor.getType() != Sensor.TYPE_ORIENTATION) {
			return;
		}
		
		Date nowDt = new Date();
		
		if( localTimeStamp != null && localTimeStamp.after(nowDt)){
			return;
		}
		
		
		// calculate the x speed
		// trying the low pass filter to get horizontal speed
		synchronized (this) {
			
			// compare initial condition
			
			mInitialX = -1 * event.values[0] ;
			mInitialY = -1 * event.values[1];
			mInitialZ = -1 * event.values[2];

			// calculate the different acceleration
//			float xAccel = lowPassFilter(event.values[0], mInitialX);
//			float yAccel = lowPassFilter(event.values[1], mInitialY);
//			float zAccel = lowPassFilter(event.values[2], mInitialZ);
 
			xAccelLabel.setText( Float.toString( mInitialX) );
			yAccelLabel.setText( Float.toString( mInitialY ) );
			zAccelLabel.setText( Float.toString( mInitialZ ) );
			
			// initial condition
			if( offsetY == 0 ){
				return;
			}
			
			// initial condition
			if( mInitialY == 0 ){
				return;
			}
			
			if(  mInitialY > 0 && mInitialY  > offsetY ){
//				sendMessage(1);
				setAlreadySent(true);
				yMaxLabel.setText( "new max: " + Float.toString(mInitialY) +
						" ofs: " + Float.toString(offsetY) );
				
			} else if(mInitialY < 0 && mInitialY < offsetY ){
				setAlreadySent(true);
				yMaxLabel.setText( "new max: " + Float.toString(mInitialY) +
						" ofs: " + Float.toString(offsetY) );
			}


		} // end of sync
		
	} // sensor changed
	
	/**
	 * Function that filters sensor data based on a weighing factor
	 * 
	 */
	private float lowPassFilter( float sensorPos, float initialPos ){
		
		// do the calculation
		float result = (sensorPos - initialPos)/mWeightFactor;
		
		return result;
	}

	
	private void sendMessage(int condition){
		
		if( isAlreadySent() ){
			return;
		}
		
		PendingIntent pi = null;
		
		SmsManager smsMan = SmsManager.getDefault();
		
		switch ( condition) {
		case 1:
			smsMan.sendTextMessage(
    				patriciaMovil, //user.getPhone(), 
    				null,
    				lateMsg, 
    				pi, null);
			break;

		default:
			smsMan.sendTextMessage(
    				patriciaMovil,  
    				null,
    				superLateMsg, 
    				pi, null);
			break;
		}
		
		textLabel.setText("Msg Sent");
	}
	
	public boolean isAlreadySent() {
		return isAlreadySent;
	}

	public void setAlreadySent(boolean isAlreadySent) {
		this.isAlreadySent = isAlreadySent;
		if( isAlreadySent ){
			confLabel.setText("-- sent --");
		} else {
			confLabel.setText("not sent");
		}
	}
	
	

	@Override
	public boolean onMenuItemSelected(int featureId, MenuItem item) {

		Log.i("LIST", "menu: " + item.getItemId() );
		switch(item.getItemId()){
		
		case R.id.add_menu:{
			Log.i("LIST", "menu selected");
//			Intent i = new Intent(this, ContactFormActivity.class);
//	        i.putExtra(NotesDbAdapter.KEY_ROWID, id);
//	        startActivityForResult(i, ACTIVITY_EDIT);
			break;
		}
		default:{
			Log.v("Contact", "other menu selected");
		}
		}// end switch
		return super.onMenuItemSelected(featureId, item);
	}
	
	

	
	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		// TODO Auto-generated method stub
		super.onActivityResult(requestCode, resultCode, data);
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		MenuInflater inflater = getMenuInflater();
		inflater.inflate(R.menu.speedy_menu, menu);
		return true;
	}
	
	
	
	
}